package com.meteor.user.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.meteor.framework.common.enums.UserAdminEnum;
import com.meteor.framework.common.exception.ServerException;
import com.meteor.framework.security.user.SecurityUser;
import com.meteor.user.entity.SysRole;
import com.meteor.user.query.SysRoleOrgQuery;
import com.meteor.user.service.*;
import com.meteor.user.vo.SysMerchantVO;
import lombok.AllArgsConstructor;
import com.meteor.framework.common.utils.PageResult;
import com.meteor.framework.mybatis.service.impl.BaseServiceImpl;
import com.meteor.user.convert.SysRoleConvert;
import com.meteor.user.mapper.SysRoleMapper;
import com.meteor.framework.common.enums.DataScopeEnum;
import com.meteor.user.query.SysRoleQuery;
import com.meteor.user.vo.SysRoleDataScopeVO;
import com.meteor.user.vo.SysRoleVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Collections;
import java.util.List;

/**
 * 角色
 *
 * @author lynn
 * @date 2024/1/03
 */
@Service
@AllArgsConstructor
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private final SysRoleMenuService sysRoleMenuService;
    private final SysRoleDataScopeService sysRoleDataScopeService;
    private final SysUserRoleService sysUserRoleService;
    private final SysUserTokenService sysUserTokenService;
    private final SysMerchantService sysMerchantService;
    private final SysOrgService sysOrgService;

    @Override
    public PageResult<SysRoleVO> page(SysRoleQuery query) {

        if(!ObjectUtils.isEmpty(query.getOrgId())){
            query.setOrgIds(sysOrgService.getSubOrgIdList(query.getOrgId()));
        }

//        IPage<SysRole> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        if(SecurityUser.getUser().getUsername().equalsIgnoreCase(UserAdminEnum.ADMIN.getValue())){
            query.setSuperAdmin(1);
        }
        IPage<SysRole> page1 = baseMapper.selectPage(getPage(query), getWrapper(query));

//        Page<SysRoleVO> page1 = baseMapper.page(getPage(query),query);

        return new PageResult<>(SysRoleConvert.INSTANCE.convertList(page1.getRecords()), page1.getTotal());
    }

    @Override
    public List<SysRoleVO> getList(SysRoleQuery query) {

        List<SysRole> entityList = baseMapper.selectList(getWrapper(query));

        return SysRoleConvert.INSTANCE.convertList(entityList);
    }

    private Wrapper<SysRole> getWrapper(SysRoleQuery query) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(query.getName()), SysRole::getName, query.getName());
        wrapper.like(StrUtil.isNotBlank(query.getRoleCode()), SysRole::getRoleCode, query.getRoleCode());
        wrapper.eq(StrUtil.isNotBlank(query.getMerchantId()), SysRole::getMerchantId, query.getMerchantId());
        wrapper.in(!ObjectUtils.isEmpty(query.getOrgIds()), SysRole::getOrgId, query.getOrgIds());

        // 数据权限
        dataScopeWrapper(wrapper);

        return wrapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysRoleVO vo) {

        SysRole entity = SysRoleConvert.INSTANCE.convert(vo);

        SysRole sysRole = baseMapper.selectOne(new QueryWrapper<SysRole>().eq("role_code", vo.getRoleCode()).eq("org_id", vo.getOrgId()));
        if(!ObjectUtils.isEmpty(sysRole)){
            throw new ServerException("角色编码已存在");
        }

        if(!SecurityUser.getUser().getUsername().equalsIgnoreCase(UserAdminEnum.ADMIN.getValue())){

            if(ObjectUtils.isEmpty(vo.getMerchantId())){
                entity.setMerchantId(SecurityUser.getUser().getMerchantId());
            }

            if(ObjectUtils.isEmpty(vo.getOrgId())){
                entity.setOrgId(SecurityUser.getUser().getOrgId());
            }
        }else{

            if(ObjectUtils.isEmpty(vo.getOrgId())) {
                throw new ServerException("请选择机构");
            }
            SysMerchantVO sysMerchantVO = sysMerchantService.orgMerchant(vo.getOrgId());
            if(!ObjectUtils.isEmpty(sysMerchantVO)){
                entity.setMerchantId(sysMerchantVO.getId());
            }
            /*if(ObjectUtils.isEmpty(vo.getMerchantId())) {
                throw new ServerException("请选择商户");
            }*/
        }

        // 保存角色
        entity.setDataScope(DataScopeEnum.SELF.getValue());
        baseMapper.insert(entity);

        // 保存角色菜单关系
        sysRoleMenuService.saveOrUpdate(entity.getId(), vo.getMenuIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRoleVO vo) {
        SysRole entity = SysRoleConvert.INSTANCE.convert(vo);

        // 更新角色
        updateById(entity);

        // 更新角色菜单关系
        sysRoleMenuService.saveOrUpdate(entity.getId(), vo.getMenuIdList());

        // 更新角色对应用户的缓存权限
        sysUserTokenService.updateCacheAuthByRoleId(entity.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dataScope(SysRoleDataScopeVO vo) {
        SysRole entity = getById(vo.getId());
        entity.setDataScope(vo.getDataScope());
        // 更新角色
        updateById(entity);

        // 更新角色数据权限关系
        if (vo.getDataScope().equals(DataScopeEnum.CUSTOM.getValue())) {
            sysRoleDataScopeService.saveOrUpdate(entity.getId(), vo.getOrgIdList());
        } else {
            sysRoleDataScopeService.deleteByRoleIdList(Collections.singletonList(vo.getId()));
        }

        // 更新角色对应用户的缓存权限
        sysUserTokenService.updateCacheAuthByRoleId(entity.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<String> idList) {
        // 删除角色
        removeByIds(idList);

        // 删除用户角色关系
        sysUserRoleService.deleteByRoleIdList(idList);

        // 删除角色菜单关系
        sysRoleMenuService.deleteByRoleIdList(idList);

        // 删除角色数据权限关系
        sysRoleDataScopeService.deleteByRoleIdList(idList);

        // 更新角色对应用户的缓存权限
        idList.forEach(sysUserTokenService::updateCacheAuthByRoleId);
    }

    @Override
    public List<SysRoleVO> roleMerchantOrg(SysRoleOrgQuery query) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if(!ObjectUtils.isEmpty(query.getMerchantId())) {
            queryWrapper.eq("merchant_id", query.getMerchantId());
        }
        if(!ObjectUtils.isEmpty(query.getOrgId())) {
            queryWrapper.eq("org_id", query.getOrgId());
        }else if(!ObjectUtils.isEmpty(query.getMerchantId())){
            queryWrapper.isNull("org_id");
        }
        queryWrapper.eq("deleted", 0);
        return SysRoleConvert.INSTANCE.convertList(baseMapper.selectList(queryWrapper));
    }

}